﻿using AspNetId4Web.Data;
using AspNetId4Web.Models;
using IdentityServer4.Validation;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AspNetId4Web
{
    /// <summary>
    /// 自定义手机验证码认证处理器
    /// </summary>
    public class PhoneCodeGrantValidator : IExtensionGrantValidator
    {
        /// <summary>
        /// 认证方式
        /// </summary>
        public string GrantType => "PhoneCodeGrantType";

        private readonly IMemoryCache _memoryCache;
        private readonly ApplicationDbContext _context;
        private readonly ILogger _logger;

        public PhoneCodeGrantValidator(
            IMemoryCache memoryCache,
            ApplicationDbContext context,
            ILogger<PhoneCodeGrantValidator> logger)
        {
            _memoryCache = memoryCache;
            _context = context;
            _logger = logger;
        }

        /// <summary>
        /// 验证自定义授权请求
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task ValidateAsync(ExtensionGrantValidationContext context)
        {
            try
            {
                //获取登录参数
                string phoneNumber = context.Request.Raw["PhoneNumber"];
                string verificationCode = context.Request.Raw["VerificationCode"];

                //获取手机号对应的缓存验证码
                if (!_memoryCache.TryGetValue(phoneNumber, out string cacheVerificationCode))
                {
                    //如果获取不到缓存验证码，说明手机号不存在，或者验证码过期，但是发送验证码时已经验证过手机号是存在的，所以只能是验证码过期
                    context.Result = new GrantValidationResult()
                    {
                        IsError = true,
                        Error = "验证码过期",
                    };

                    return;
                }

                if (verificationCode != cacheVerificationCode)
                {
                    context.Result = new GrantValidationResult()
                    {
                        IsError = true,
                        Error = "验证码错误",
                    };

                    return;
                }

                //根据手机号获取用户信息
                var appUser = await GetUserByPhoneNumberAsync(phoneNumber);
                if (appUser == null)
                {
                    context.Result = new GrantValidationResult()
                    {
                        IsError = true,
                        Error = "手机号无效",
                    };

                    return;
                }

                //授权通过返回
                context.Result = new GrantValidationResult(appUser.Id.ToString(), "custom");
            }
            catch (Exception ex)
            {
                context.Result = new GrantValidationResult()
                {
                    IsError = true,
                    Error = ex.Message
                };
            }
        }

        //根据手机号获取用户信息
        private async Task<ApplicationUser> GetUserByPhoneNumberAsync(string phoneNumber)
        {
            var appUser = await _context.Users.AsNoTracking()
                .FirstOrDefaultAsync(x => x.PhoneNumber == phoneNumber);

            return appUser;
        }

    }
}
